package com.fingard.dsp.bank.directbank.weixin01.domain.common;

import com.fingard.dsp.bank.directbank.weixin01.domain.entity.SuccessRateData;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.Random;

/**
 * 【跨城冗灾】工具类
 * @author liujinhui
 */
public class DomainUtil {

    // 随机数对象
    private static Random random = new Random();
    // 比率总数
    public static final double RATE_COUNT = 100;
    // 上报数据计算前最小大小
    public static final int MIN_DATA_SIZE = 50;
    // 请求超时时间（毫秒）
    public static final int MIN_TIME_OUT = 2000;
    // 域名请求前缀
    public static final String HTTPS_PREFIX = "https://";
    // 数据当前时间往前保留多长时间（毫秒）
    public static final int BEFORE_TIME = 10 * 60 * 1000;
    // 比率设置(例如：100为百分百，1000为千分比，10000为万分比)
    public static final int maxRate = 10000;

    /**
     * 通过域名测试API服务器是否正常
     * @param domain
     * @return
     */
    public static boolean domainLinkTest(String domain) {
        boolean bo = true;
        String url = HTTPS_PREFIX + domain;
        try {
            URL urlObj = new URL(url);
            HttpURLConnection oc = (HttpURLConnection) urlObj.openConnection();
            oc.setUseCaches(false);
            oc.setConnectTimeout(MIN_TIME_OUT);
            oc.getResponseCode();
        } catch (UnknownHostException e) {
            bo = false;
        } catch (SocketTimeoutException e) {
            bo = false;
        } catch (IOException e) {
            bo = false;
        }
        return bo;
    }

    /**
     * 根据上报结果计算成功率
     * @param dataList 上报结果
     * @return
     */
    public static double computeRate(LinkedList<SuccessRateData> dataList) {
        // 获取10分钟前的时间戳
        Long upTime = System.currentTimeMillis() - BEFORE_TIME;
        // 计算10分钟内总请求数和错误数
        int allCount = 0;
        int errorCount = 0;
        if (dataList != null && dataList.size() > 0) {
            for (SuccessRateData data : dataList) {
                if (upTime < data.getTime()) {
                    allCount++;
                    if (DomainConstants.ReportResult.FAIL.equals(data.getReportResult())) {
                        errorCount++;
                    }
                }
            }
        }
        // 计算主域名成功率(失败数小于0或总数少于50成功率为100%)
        double rate = RATE_COUNT;
        if (errorCount > 0 && allCount >= MIN_DATA_SIZE) {
            rate = ((double) (allCount - errorCount) / (double) allCount) * 100;
        }
        return rate;
    }

    /**
     * 通过主域名实现双活(根据参考比率值计算是否使用备用域名并返回)
     * @param domain 当前域名
     * @param referRate 参考比率
     * @return
     */
    public static String reserveRate(String domain, int referRate) {
        String newDomain = domain;
        // 通过备用域名出现比率计算是否使用备用域名
        boolean reserve = false;
        int rate = random.nextInt(maxRate) % maxRate + 1;
        if (rate <= referRate) {
            reserve = true;
        }
        // 当前为主域名并且满足备用域名启用比率的情况下始终返回备用域名
        if (domain.equals(DomainConstants.API_WEIXIN_DOMAIN) && reserve) {
            newDomain = DomainConstants.API_WEIXIN_RESERVE_DOMAIN;
        }
        if (domain.equals(DomainConstants.API_MCH_WEIXIN_DOMAIN) && reserve) {
            newDomain = DomainConstants.API_MCH_WEIXIN_RESERVE_DOMAIN;
        }
        return newDomain;
    }

    /**
     * 字符串空值判断
     * @param str
     * @return
     */
    public static boolean StringIsEmpty(String str) {
        boolean bo = false;
        if (str == null || "".equals(str)) {
            bo = true;
        }
        return bo;
    }
}
